#include "upload.h"

#include "include.h"

unsigned short (*upload_package)( void );

// CRC16 checkout func
uint8_t PY_CRC_8_T8_MODBUS_i(uint8_t *di, uint32_t len)
{
	uint16_t crc_poly = 0xA001; // Bit sequence inversion of 0x8005
	uint8_t data_t = 0xFF; // CRC register

    for(uint32_t i = 0; i < len; i++)
    {
    	data_t ^= di[i]; // 8-bit data

        for (uint8_t j = 0; j < 8; j++)
        {
            if (data_t & 0x0001)
            	data_t = (data_t >> 1) ^ crc_poly;
            else
            	data_t >>= 1;
        }
    }
    return data_t;
}

uint64_t analysis_decimals( float decimals )       // 解析小数
{
  uint64_t  value = 0;
  uint64_t  decimals_64 = 0;
  uint64_t  temp   = 0;
  uint64_t  byte1 = 0;
  uint64_t  byte2 = 0;
  uint64_t  byte3 = 0;
  uint64_t  byte4 = 0;
  uint64_t  byte5 = 0;
  decimals_64 = (uint64_t)(decimals * 1000.0f);

  temp  = decimals_64 % 100;
  byte1 = (temp / 10) * 16  + (temp  % 10);

  temp = (decimals_64 % 10000) / 100;
  byte2 = (temp / 10) * 16  + (temp  % 10);

  temp = (decimals_64 % 1000000) / 10000;
  byte3 = (temp / 10) * 16  + (temp  % 10);

  temp = (decimals_64 % 100000000) / 1000000;
  byte4 = (temp / 10) * 16  + (temp  % 10);

  if( decimals < 0 )
  {
    byte5 = 0xF0;
  }
  else
  {
    byte5 = 0x00;
  }
  value = byte1 << 32 | byte2 << 24 | byte3 << 16 | byte4 << 8 | byte5;
  return value;
}

uint16_t tx_buf[10] = {0x1111, 0x2222};

uint64_t analysis_integer( int32_t integer )       // /解析整数
{
  uint64_t  value = 0;
  uint64_t  temp  = 0;
  uint64_t  byte1 = 0;
  uint64_t  byte2 = 0;
  uint64_t  byte3 = 0;
  uint64_t  byte4 = 0;
  uint64_t  byte5 = 0;


  temp  = integer % 100;
  byte1 = (temp / 10) * 16 + (temp  % 10);

  temp = (integer % 10000) / 100;
  byte2 = (temp / 10) * 16 + (temp  % 10);

  temp = (integer % 1000000) / 10000;
  byte3 = (temp / 10) * 16 + (temp  % 10);

  temp = (integer % 100000000) / 1000000;
  byte4 = (temp / 10) * 16 + (temp  % 10);

  temp = (integer % 10000000000) / 100000000;
  byte5 = (temp / 10) * 16 + (temp  % 10);

  value = byte1 << 32 | byte2 << 24 | byte3 << 16 | byte4 << 8 | byte5;
  return value;
}

void upload_package_init(void )
{
  memset( rk.upload.txbuf, 0, Upload_Data_Len_Max );

  rk.upload.txbuf[0] = 0x68;       // start char

  rk.upload.txbuf[1] = 0x00;       // len

  rk.upload.txbuf[2] = 0x68;       // start char

  if( upload_package == upload_confirm_package )
  {
    if( ((rk.upload.confirm_type & 0xf0) == 0x80) || ((rk.upload.confirm_type & 0xf0) == 0x90)  )
    {
      rk.upload.txbuf[3] = 0x80;       // control domain
    }
    else
    {
      rk.upload.txbuf[3] = 0x8E;       // control domain
    }
  }
  else
  {
    rk.upload.txbuf[3] = 0x8E;       // control domain
  }


  if( upload_package == upload_get_Whether_valid_addr_package )
  {
    memcpy( rk.upload.txbuf+Package_Addr_Data_Pos, recv_uart_array_addr, Addr_Len );
  }
  else
  {
    memcpy( rk.upload.txbuf+Package_Addr_Data_Pos, &rk.hyper_parameter.addr, Addr_Len );
  }
}

void set_device_upload_cycle( uint8_t *cycle )
{
  rk.parameter.func_data_cycle = ((cycle[0] << 8) | (cycle[1] << 0)) * A_Minute;
  rk.parameter.THA_data_cycle  = ((cycle[2] << 8 ) | (cycle[3] << 0 )) * A_Minute;
  initflag_set( Extflash_Init_Flag );
  HAL_Delay(20);
  hyper_parameter_set();
  HAL_Delay(20);
  parameter_set();
  HAL_Delay(20);
  if( rk.parameter.control_object == Remote_Control_Mode )
  {
    rk.upload.confirm_type       = AFN_Set_Device_Upload_Cycle;
  }
}
void set_device_upload_target( uint8_t *data )
{
  memcpy( rk.hyper_parameter.upload_target_server_ip, data, sizeof(rk.hyper_parameter.upload_target_server_ip) );
  rk.hyper_parameter.upload_target_port = (data[4] << 8) | data[5];
  initflag_set( Extflash_Init_Flag );
  HAL_Delay(20);
  hyper_parameter_set();
  HAL_Delay(20);
  parameter_set();
  HAL_Delay(20);
  if( rk.parameter.control_object == Remote_Control_Mode )
  {
    rk.upload.confirm_type = AFN_Set_Device_Upload_Target;
  }
}

void AUX_package( unsigned short datapos )
{
  // AUX
  if( !rk.parameter.whether_use_password  )
  {
    rk.upload.txbuf[datapos  ] = 0x00;
    rk.upload.txbuf[datapos+1] = 0x00;
    datapos += 2;
  }
  else
  {
    rk.upload.txbuf[datapos  ] = rk.hyper_parameter.password >> 8;
    rk.upload.txbuf[datapos+1] = rk.hyper_parameter.password;
    datapos += 2;
  }
  // Get RTC
  RTC_TimeTypeDef rTime 	= {0};
  RTC_DateTypeDef rDate 	= {0};
  HAL_RTC_GetTime(&hrtc, &rTime, RTC_FORMAT_BIN);
  HAL_RTC_GetDate(&hrtc, &rDate, RTC_FORMAT_BIN);

  rk.upload.txbuf[datapos  ] = rDate.Year;
  rk.upload.txbuf[datapos+1] = rDate.Month;
  rk.upload.txbuf[datapos+2] = rDate.Date;
  rk.upload.txbuf[datapos+3] = rTime.Hours;
  rk.upload.txbuf[datapos+4] = rTime.Minutes;
  rk.upload.txbuf[datapos+5] = rTime.Seconds;
  datapos += 6;

}

// 回复服务器恢复出厂设置
unsigned short upload_reset_app_bin_package( void )
{
  unsigned short datapos   = Package_User_Data_Region_Size;

  // user data region
  rk.upload.txbuf[datapos]   = AFN_Reset_App_Bin;         // 应用功能码
  datapos += 1;

  rk.upload.txbuf[datapos]   = 0x0A;              // 执行结果
  datapos += 1;

  return (datapos - Package_User_Data_Region_Size);// 用户数据域长度
}

unsigned short upload_start_iap_update_package( void )
{
  unsigned short datapos   = Package_User_Data_Region_Size;

  // user data region
  rk.upload.txbuf[datapos]   = AFN_IAP_Update_Start;         // 应用功能码
  datapos += 1;

  rk.upload.txbuf[datapos]   = 0x0A;              // 执行结果
  datapos += 1;

  return (datapos - Package_User_Data_Region_Size);// 用户数据域长度
}
// 打包回复升级包
unsigned short upload_iap_package( void )
{
  unsigned short datapos   = Package_User_Data_Region_Size;

  // user data region
  rk.upload.txbuf[datapos]   = AFN_IAP_Update_Work;         // 应用功能码
  datapos += 1;
  if( iap_btld.error_type == 0x00 )
  {
    rk.upload.txbuf[datapos]   = 0x0A;              // 执行结果
  }
  else
  {
    rk.upload.txbuf[datapos]   = 0x0B;              // 执行结果
  }
  datapos += 1;

  rk.upload.txbuf[datapos]   = iap_btld.error_type;              // 错误类型
  datapos += 1;
  rk.upload.txbuf[datapos]   = iap_btld.now_count<<8;              // 当前包序
  rk.upload.txbuf[datapos++] = iap_btld.now_count;              // 当前包序
  datapos += 2;

  return (datapos - Package_User_Data_Region_Size);// 用户数据域长度
}
// 打包回复确认包
unsigned short upload_confirm_package( void )
{
  unsigned short datapos = Package_User_Data_Region_Size;

  // user data region
  rk.upload.txbuf[datapos] = rk.upload.confirm_type;         // 应用功能码
  datapos += 1;

  rk.upload.txbuf[datapos] = 0x0A;              // 执行结果
  datapos += 1;

  AUX_package( datapos );
  datapos += 8;

  return (datapos - Package_User_Data_Region_Size);// 用户数据域长度
}
// 打包注册包
unsigned short upload_login_package( void )
{
  unsigned short datapos = Package_User_Data_Region_Size; // 应用数据域基地址
  int16_t temp = 0;
  // user data region
  rk.upload.txbuf[datapos] = AFN_Login;      // 应用功能码
  datapos += 1;
  temp = (int16_t)(rk.hyper_parameter.software_version * 10);
  rk.upload.txbuf[datapos  ] = temp >> 8;
  rk.upload.txbuf[datapos+1] = temp;
  datapos += 2;
  temp = (int16_t)(rk.hyper_parameter.hardware_version * 10);
  rk.upload.txbuf[datapos  ] = temp >> 8;
  rk.upload.txbuf[datapos+1] = temp;
  datapos += 2;
  rk.upload.txbuf[datapos] = rk.parameter.whether_use_password;
  datapos += 1;

  // AUX
  AUX_package( datapos );
  datapos += 8;

  return (datapos - Package_User_Data_Region_Size);// 用户数据域长度
}
// 询问是否为有效地址
unsigned short upload_get_Whether_valid_addr_package( void )
{
  unsigned short datapos = Package_User_Data_Region_Size; // 应用数据域基地址

  // user data region
  rk.upload.txbuf[datapos] = AFN_Get_Whether_Valid_Addr;      // 应用功能码
  datapos += 1;
  // AUX
  AUX_package( datapos );
  datapos += 8;

  return (datapos - Package_User_Data_Region_Size);// 用户数据域长度
}
// 打包心跳包
unsigned short upload_heartbeat_package( void )
{
  unsigned short datapos = Package_User_Data_Region_Size; // 应用数据域基地址

  // user data region
  rk.upload.txbuf[datapos] = AFN_Heart;      // 应用功能码 心跳 0x01
  datapos += 1;
  rk.upload.txbuf[datapos] = 0xAA;
  datapos += 1;
  // AUX
  AUX_package( datapos );
  datapos += 8;

  return (datapos - Package_User_Data_Region_Size);// 用户数据域长度
}
// 打包切换模式包
unsigned short upload_switch_mode_package( void )
{
  unsigned short datapos = Package_User_Data_Region_Size;

  // user data region
  rk.upload.txbuf[datapos] = AFN_Mode; // 应用功能码
  datapos += 1;
  rk.upload.txbuf[datapos] = rk.parameter.control_object; // 切换控制对象 （远程 现地）
  datapos += 1;
  // AUX
  AUX_package( datapos );
  datapos += 8;
  return (datapos - Package_User_Data_Region_Size);// 用户数据域长度
}
// 打包闸门运动包
unsigned short upload_gate_move_package( void )
{
  unsigned short datapos = Package_User_Data_Region_Size;
  uint64_t temp = 0;
  // user data region
  rk.upload.txbuf[datapos] = AFN_Move; // 应用功能码
  datapos += 1;

  rk.upload.txbuf[datapos] = rk.gate.detection_move_state;     // 运动状态
  datapos += 1;

  temp = analysis_integer( rk.gate.position );  // 闸位

  rk.upload.txbuf[datapos+0] = (temp >> 32) & 0xFF;
  rk.upload.txbuf[datapos+1] = (temp >> 24) & 0xFF;
  rk.upload.txbuf[datapos+2] = (temp >> 16) & 0xFF;
  rk.upload.txbuf[datapos+3] = (temp >> 8 ) & 0xFF;
  rk.upload.txbuf[datapos+4] = (temp >> 0 ) & 0xFF;

  datapos += 5;

  // AUX
  AUX_package( datapos );
  datapos += 8;
  return (datapos - Package_User_Data_Region_Size);// 用户数据域长度
}

// 打包闸门运动到极限值
unsigned short upload_gate_move_limit_package( void )
{
  unsigned short datapos = Package_User_Data_Region_Size;
  uint64_t temp = 0;
  // user data region
  rk.upload.txbuf[datapos] = AFN_Move_Limit; // 应用功能码
  datapos += 1;

  rk.upload.txbuf[datapos] = rk.gate.move_limit_pos;     // 运动状态
  datapos += 1;

  temp = analysis_integer( rk.gate.position );  // 闸位

  rk.upload.txbuf[datapos+0] = (temp >> 32) & 0xFF;
  rk.upload.txbuf[datapos+1] = (temp >> 24) & 0xFF;
  rk.upload.txbuf[datapos+2] = (temp >> 16) & 0xFF;
  rk.upload.txbuf[datapos+3] = (temp >> 8 ) & 0xFF;
  rk.upload.txbuf[datapos+4] = (temp >> 0 ) & 0xFF;

  datapos += 5;
  // AUX
  AUX_package( datapos );
  datapos += 8;
  return (datapos - Package_User_Data_Region_Size);// 用户数据域长度
}

// 打包报警包
unsigned short upload_alarm_package( void )
{
  unsigned short datapos = Package_User_Data_Region_Size;
  rk.upload.txbuf[3] = 0x8D;       // control domain
  // user data region
  rk.upload.txbuf[datapos] = AFN_Alarm;         // 应用功能码
  datapos += 1;

  rk.upload.txbuf[datapos] = rk.upload.alarm_type;              // 报警类型
  datapos += 1;

  rk.upload.txbuf[datapos] = rk.upload.alarm_status;
  datapos += 1;

  // AUX
  AUX_package( datapos );
  datapos += 8;
  return (datapos - Package_User_Data_Region_Size);// 用户数据域长度
}

// 打包故障包
unsigned short upload_malfunction_package( void )
{
  unsigned short datapos = Package_User_Data_Region_Size;

  // user data region
  rk.upload.txbuf[datapos] = AFN_Malfunction;         // 应用功能码
  datapos += 1;

  rk.upload.txbuf[datapos] = rk.upload.malfunction_type;              // 故障类型     ！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！
  datapos += 1;

  rk.upload.txbuf[datapos] = rk.upload.malfunction_status;              // 故障状态     ！！！！！！！！！！！！！！！！！！！！！
  datapos += 1;

  // AUX
  AUX_package( datapos );
  datapos += 8;
  return (datapos - Package_User_Data_Region_Size);// /用户数据域长度
}
// 打包工况数据包
unsigned short upload_THA_data_package( void )
{
  int temp = 0;
  unsigned short datapos = Package_User_Data_Region_Size;

  // user data region
  if( rk.flag.THA_data_initiative_update == true )
  {
    rk.upload.txbuf[datapos] = AFN_THA_Data;
    rk.flag.THA_data_initiative_update = false;
  }
  else
  {
    rk.upload.txbuf[datapos] = AFN_Call_THA_Data;
  }
  datapos += 1;

  // A相电压
  rk.upload.txbuf[datapos  ] = 0xFF;
  rk.upload.txbuf[datapos+1] = 0xFF;
  rk.upload.txbuf[datapos+2] = 0xFF;
  datapos += 3;

  // B相电压
  rk.upload.txbuf[datapos  ] = 0xFF;
  rk.upload.txbuf[datapos+1] = 0xFF;
  rk.upload.txbuf[datapos+2] = 0xFF;
  datapos += 3;

  // C相电压
  rk.upload.txbuf[datapos  ] = 0xFF;
  rk.upload.txbuf[datapos+1] = 0xFF;
  rk.upload.txbuf[datapos+2] = 0xFF;
  datapos += 3;

  // A相电流
  rk.upload.txbuf[datapos  ] = 0xFF;
  rk.upload.txbuf[datapos+1] = 0xFF;
  rk.upload.txbuf[datapos+2] = 0xFF;
  datapos += 3;

  // B相电流
  rk.upload.txbuf[datapos  ] = 0xFF;
  rk.upload.txbuf[datapos+1] = 0xFF;
  rk.upload.txbuf[datapos+2] = 0xFF;
  datapos += 3;

  // C相电流
  rk.upload.txbuf[datapos  ] = 0xFF;
  rk.upload.txbuf[datapos+1] = 0xFF;
  rk.upload.txbuf[datapos+2] = 0xFF;
  datapos += 3;

  // 太阳能板电压
  rk.upload.txbuf[datapos  ] = 0xFF;
  rk.upload.txbuf[datapos+1] = 0xFF;
  rk.upload.txbuf[datapos+2] = 0xFF;
  datapos += 3;

  // 太阳能板电流
  rk.upload.txbuf[datapos  ] = 0xFF;
  rk.upload.txbuf[datapos+1] = 0xFF;
  rk.upload.txbuf[datapos+2] = 0xFF;
  datapos += 3;

  // 蓄电池电压
  temp = (int)rk.ina226.voltage;
  rk.upload.txbuf[datapos  ] = temp >> 16;
  rk.upload.txbuf[datapos+1] = temp >> 8;
  rk.upload.txbuf[datapos+2] = temp;
  datapos += 3;

  // 蓄电池电流
  temp = (int)rk.ina226.current;
  rk.upload.txbuf[datapos  ] = temp >> 16;
  rk.upload.txbuf[datapos+1] = temp >> 8;
  rk.upload.txbuf[datapos+2] = temp;
  datapos += 3;

  // 蓄电池剩余电量
  rk.upload.txbuf[datapos  ] = 0xFF;
  rk.upload.txbuf[datapos+1] = 0xFF;
  rk.upload.txbuf[datapos+2] = 0xFF;
  datapos += 3;

  // 无线信号强度
 rk.ec20.signal_strength_value = 20 + (rk.timer.EC20_init_timer % 10);

  rk.upload.txbuf[datapos  ] = 0x00;
  rk.upload.txbuf[datapos+1] = 0x00;
  rk.upload.txbuf[datapos+2] = rk.ec20.signal_strength_value;
  datapos += 3;

  // 4G剩余流量
  rk.upload.txbuf[datapos  ] = 0x00;
  rk.upload.txbuf[datapos+1] = 0x00;
  rk.upload.txbuf[datapos+2] = 0xFF;
  datapos += 3;

  // AUX
  AUX_package( datapos );
  datapos += 8;
  return (datapos - Package_User_Data_Region_Size);// 用户数据域长度
}

// 打包业务数据包
unsigned short upload_function_data_package( void )
{
  uint64_t temp = 0;
  unsigned short datapos = Package_User_Data_Region_Size;

  // user data region
  if( rk.flag.func_data_initiative_update == true )
  {
    rk.upload.txbuf[datapos] = AFN_Fanction_Data;         // 应用功能
    rk.flag.func_data_initiative_update = false;
  }
  else
  {
    rk.upload.txbuf[datapos] = rk.upload.AFN_call_type;
  }
  datapos += 1;
  if( rk.upload.AFN_call_type == AFN_History_Call_Fanction_Data )
  {
    rk.upload.txbuf[datapos+0] = 0x01;
    rk.upload.txbuf[datapos+1] = 0x00;
    rk.upload.txbuf[datapos+2] = 0x01;
    rk.upload.txbuf[datapos+3] = 0x00;
    rk.upload.txbuf[datapos+4] = 0x01;
    datapos += 5;
  }


  // 闸前水位
  temp = analysis_decimals( rk.flowmeter.gata_front_water_stage );
  rk.upload.txbuf[datapos+0] = (temp >> 32) & 0xFF;
  rk.upload.txbuf[datapos+1] = (temp >> 24) & 0xFF;
  rk.upload.txbuf[datapos+2] = (temp >> 16) & 0xFF;
  rk.upload.txbuf[datapos+3] = (temp >> 8 ) & 0xFF;
  rk.upload.txbuf[datapos+4] = (temp >> 0 ) & 0xFF;
  datapos += 5;

  // 闸后水位
  temp = analysis_decimals( rk.flowmeter.gata_back_water_stage );
  rk.upload.txbuf[datapos+0] = (temp >> 32) & 0xFF;
  rk.upload.txbuf[datapos+1] = (temp >> 24) & 0xFF;
  rk.upload.txbuf[datapos+2] = (temp >> 16) & 0xFF;
  rk.upload.txbuf[datapos+3] = (temp >> 8 ) & 0xFF;
  rk.upload.txbuf[datapos+4] = (temp >> 0 ) & 0xFF;
  datapos += 5;

  // 闸位
  temp = analysis_integer( rk.gate.position );
  rk.upload.txbuf[datapos+0] = (temp >> 32) & 0xFF;
  rk.upload.txbuf[datapos+1] = (temp >> 24) & 0xFF;
  rk.upload.txbuf[datapos+2] = (temp >> 16) & 0xFF;
  rk.upload.txbuf[datapos+3] = (temp >> 8 ) & 0xFF;
  rk.upload.txbuf[datapos+4] = (temp >> 0 ) & 0xFF;
  datapos += 5;

  // 瞬时流速
  temp = analysis_decimals( rk.flowmeter.instant_speed );
  rk.upload.txbuf[datapos+0] = (temp >> 32) & 0xFF;
  rk.upload.txbuf[datapos+1] = (temp >> 24) & 0xFF;
  rk.upload.txbuf[datapos+2] = (temp >> 16) & 0xFF;
  rk.upload.txbuf[datapos+3] = (temp >> 8 ) & 0xFF;
  rk.upload.txbuf[datapos+4] = (temp >> 0 ) & 0xFF;
  datapos += 5;

  // 瞬时流量
  temp = analysis_decimals( rk.flowmeter.instant_water_discharge );
  rk.upload.txbuf[datapos+0] = (temp >> 32) & 0xFF;
  rk.upload.txbuf[datapos+1] = (temp >> 24) & 0xFF;
  rk.upload.txbuf[datapos+2] = (temp >> 16) & 0xFF;
  rk.upload.txbuf[datapos+3] = (temp >> 8 ) & 0xFF;
  rk.upload.txbuf[datapos+4] = (temp >> 0 ) & 0xFF;
  datapos += 5;

  // 累计流量
  temp = analysis_integer( rk.flowmeter.acc_water_discharge );
  rk.upload.txbuf[datapos+0] = (temp >> 32) & 0xFF;
  rk.upload.txbuf[datapos+1] = (temp >> 24) & 0xFF;
  rk.upload.txbuf[datapos+2] = (temp >> 16) & 0xFF;
  rk.upload.txbuf[datapos+3] = (temp >> 8 ) & 0xFF;
  rk.upload.txbuf[datapos+4] = (temp >> 0 ) & 0xFF;
  datapos += 5;

  // 流体电导比 ！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！
  rk.upload.txbuf[datapos  ] = 0xFF;
  rk.upload.txbuf[datapos+1] = 0xFF;
  rk.upload.txbuf[datapos+2] = 0xFF;
  rk.upload.txbuf[datapos+3] = 0xFF;
  rk.upload.txbuf[datapos+4] = 0xFF;
  datapos += 5;

  // 渗透水压力！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！
  rk.upload.txbuf[datapos  ] = 0xFF;
  rk.upload.txbuf[datapos+1] = 0xFF;
  rk.upload.txbuf[datapos+2] = 0xFF;
  rk.upload.txbuf[datapos+3] = 0xFF;
  rk.upload.txbuf[datapos+4] = 0xFF;
  datapos += 5;

  // 荷重！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！
  rk.upload.txbuf[datapos  ] = 0xFF;
  rk.upload.txbuf[datapos+1] = 0xFF;
  rk.upload.txbuf[datapos+2] = 0xFF;
  rk.upload.txbuf[datapos+3] = 0xFF;
  rk.upload.txbuf[datapos+4] = 0xFF;
  datapos += 5;

  // 温度
  temp = analysis_decimals( rk.ds18b20.temperature );
  rk.upload.txbuf[datapos+0] = (temp >> 32) & 0xFF;
  rk.upload.txbuf[datapos+1] = (temp >> 24) & 0xFF;
  rk.upload.txbuf[datapos+2] = (temp >> 16) & 0xFF;
  rk.upload.txbuf[datapos+3] = (temp >> 8 ) & 0xFF;
  rk.upload.txbuf[datapos+4] = (temp >> 0 ) & 0xFF;
  datapos += 5;

  // 模式（对象：远程 现地）
  rk.upload.txbuf[datapos] = rk.parameter.control_object;
  datapos += 1;

  // 闸门运动状态
  rk.upload.txbuf[datapos] = rk.gate.detection_move_state;
  datapos += 1;

  // AUX
  AUX_package( datapos );
  datapos += 8;
  return (datapos - Package_User_Data_Region_Size);// 用户数据域长度
}


// 打包超参数数据包
unsigned short upload_hyper_parameter_package( void )
{
  unsigned short datapos = Package_User_Data_Region_Size;

  rk.upload.txbuf[datapos] = rk.upload.AFN_call_type;
  datapos += 1;

  memcpy( rk.upload.txbuf+datapos, &rk.hyper_parameter, sizeof(rk.hyper_parameter) );

  datapos += Hyp_Pam_Len;
  // AUX
  AUX_package( datapos );
  datapos += 8;
  return (datapos - Package_User_Data_Region_Size);// 用户数据域长度
}
// 打包结束加校验
void upload_package_crc_end( uint16_t user_data_regsion_len )
{
  uint8_t  temp        = 0;
  uint8_t  CS_checknum = 0;
  uint16_t datalen     = user_data_regsion_len + Package_Control_Region_Size + Package_Addr_Region_Size;         // 用户数据区长度
  uint16_t datapos     = datalen + Package_Head_Size;


  // len
  if( datalen <= 0xFF )
    rk.upload.txbuf[1] = datalen;
  else
  {
    rk.upload.txbuf[1] = datalen & 0xFF;
    temp = (datalen & 0x700) >> 4;
    rk.upload.txbuf[3] = temp;
  }
  // cs check

  for( int i = Package_Control_Data_Pos; i < Package_Control_Data_Pos + datalen; i++ )
  {
    CS_checknum += rk.upload.txbuf[i];
  }

  rk.upload.txbuf[datapos] = CS_checknum;
  datapos += 1;
  // end
  rk.upload.txbuf[datapos] = End_Char;
  datapos += 1;

  if( (rk.upload.txbuf[Package_User_Data_Region_Size] == AFN_Login) || ( rk.upload.txbuf[Package_User_Data_Region_Size] == AFN_Set_Device_Clock ))
  {
    return ;
  }

  push_sub_package_into_exflash( &rk.flash_cycle_queue, rk.upload.txbuf );
}

// 扫描报警信号
void scan_alarm_signal( void )
{
  static int voltage_lower_limit_alarm_count                    = 0;
  static int voltage_upper_limit_alarm_count                    = 0;
  static int current_upper_limit_alarm_count                    = 0;
  static int gate_front_water_stage_upper_limit_alarm_count     = 0;
  static int gate_position_limit_alarm_count                    = 0;

  if( rk.upload.scan_alarm_step == 6 )
  {
    rk.upload.scan_alarm_step = 0;
  }
  // 蓄电池24v 欠压
  if( rk.upload.scan_alarm_step == 0 )
  {
    if( (rk.ina226.voltage <= rk.hyper_parameter.voltage_lower_limit) )
    {
      if( voltage_lower_limit_alarm_count == 0 )
      {
        rk.upload.alarm_status = Alarming;
        rk.upload.alarm_type   = Battery_P24V_Undervoltage;
        upload_package         = upload_alarm_package;
        upload_package_init();
        upload_package_crc_end( upload_package() );
        rk.flag.upload_alarming_P24V_Undervoltage = true;

      }
      else
      {

        if( voltage_lower_limit_alarm_count == ((Alarm_Upload_Timer * 60) / (8 * (Scan_Alarm_Interval / A_Second)))  )
        {
          voltage_lower_limit_alarm_count = 0;
        }
      }
      voltage_lower_limit_alarm_count++;
    }
    else
    {
      // 当前报警状态解除
      if( rk.flag.upload_alarming_P24V_Undervoltage  )
      {
        rk.upload.alarm_status = Release_Alarm;
        rk.upload.alarm_type   = Battery_P24V_Undervoltage;
        upload_package         = upload_alarm_package;
        upload_package_init();
        upload_package_crc_end( upload_package() );
        rk.flag.upload_alarming_P24V_Undervoltage = false;
      }
    }
  }
  // 蓄电池24v 过压
  else if( rk.upload.scan_alarm_step == 1 )
  {
    if( (rk.ina226.voltage >= rk.hyper_parameter.voltage_upper_limit) )
    {
      if( voltage_upper_limit_alarm_count == 0 )
      {
        rk.flag.upload         = true;
        rk.upload.alarm_status = Alarming;
        rk.upload.alarm_type   = Battery_P24V_Overvoltage;
        upload_package         = upload_alarm_package;
        upload_package_init();
        upload_package_crc_end( upload_package() );
        rk.flag.upload_alarming_P24V_Overvoltage = true;
      }
      else
      {

        if( voltage_upper_limit_alarm_count == ((Alarm_Upload_Timer * 60) / (8 * (Scan_Alarm_Interval / A_Second)))  )
        {
          voltage_upper_limit_alarm_count = 0;
        }
      }
      voltage_upper_limit_alarm_count++;
    }
    else
    {

      if( rk.flag.upload_alarming_P24V_Overvoltage )
      {
        rk.flag.upload         = true;
        rk.upload.alarm_status = Release_Alarm;
        rk.upload.alarm_type   = Battery_P24V_Overvoltage;
        upload_package         = upload_alarm_package;
        upload_package_init();
        upload_package_crc_end( upload_package() );
        rk.flag.upload_alarming_P24V_Overvoltage = false;
      }
    }
  }
  // 蓄电池24v 过流
  else if( rk.upload.scan_alarm_step == 2 )
  {
    if( (rk.ina226.current_outcnt >= 1 ) )
    {
      if( current_upper_limit_alarm_count == 0 )
      {
        rk.flag.upload         = true;
        rk.upload.alarm_status = Alarming;
        rk.upload.alarm_type   = Battery_P24V_Overcurrent;
        upload_package         = upload_alarm_package;
        upload_package_init();
        upload_package_crc_end( upload_package() );
        rk.flag.upload_alarming_P24V_Overcurrent = true;
      }
      else
      {
        if( current_upper_limit_alarm_count == ((Alarm_Upload_Timer * 60) / (8 * (Scan_Alarm_Interval / A_Second)))  )
        {
          current_upper_limit_alarm_count = 0;
        }
      }
      current_upper_limit_alarm_count++;
    }
    else
    {
      if( rk.flag.upload_alarming_P24V_Overcurrent )
      {
        rk.flag.upload         = true;
        rk.upload.alarm_status = Release_Alarm;
        rk.upload.alarm_type   = Battery_P24V_Overcurrent;
        upload_package         = upload_alarm_package;
        upload_package_init();
        upload_package_crc_end( upload_package() );
        rk.flag.upload_alarming_P24V_Overcurrent = false;
      }
    }
  }
  // 蓄电池24v 低电量
  else if( rk.upload.scan_alarm_step == 3 )
  {

  }
  // 水位超限
  else if( rk.upload.scan_alarm_step == 4 )
  {
    if( rk.CONFIG.FLOWMETER == okey )
    {
      if( (rk.flowmeter.water_level >= rk.hyper_parameter.gate_front_water_stage_upper_limit) )
      {
        if( gate_front_water_stage_upper_limit_alarm_count == 0 )
        {
          rk.flag.upload         = true;
          rk.upload.alarm_status = Alarming;
          rk.upload.alarm_type   = Water_Level_Overlimit;
          upload_package         = upload_alarm_package;
          upload_package_init();
          upload_package_crc_end( upload_package() );
          rk.flag.upload_alarming_Water_Level_Overlimit = true;
        }
        else
        {

          if( gate_front_water_stage_upper_limit_alarm_count == ((Alarm_Upload_Timer * 60) / (8 * (Scan_Alarm_Interval / A_Second)))  )
          {
            gate_front_water_stage_upper_limit_alarm_count = 0;
          }
        }
        gate_front_water_stage_upper_limit_alarm_count++;
      }
      else
      {
        if( rk.flag.upload_alarming_Water_Level_Overlimit )
        {
          rk.flag.upload         = true;
          rk.upload.alarm_status = Release_Alarm;
          rk.upload.alarm_type   = Water_Level_Overlimit;
          upload_package         = upload_alarm_package;
          upload_package_init();
          upload_package_crc_end( upload_package() );
          rk.flag.upload_alarming_Water_Level_Overlimit = false;
        }
      }
    }
  }
    // 闸位超限
  else if( rk.upload.scan_alarm_step == 5 )
  {
    if( rk.CONFIG.ENCODER == okey )
    {

      if( (rk.gate.position > rk.hyper_parameter.gate_height)  )
      {
        if( gate_position_limit_alarm_count == 0 )
        {
          rk.flag.upload         = true;
          rk.upload.alarm_status = Alarming;
          rk.upload.alarm_type   = Gate_Positon_Overlimit;
          upload_package         = upload_alarm_package;
          upload_package_init();
          upload_package_crc_end( upload_package() );
          rk.flag.upload_alarming_Gate_Positon_Overlimit = true;
        }
        else
        {

          if( gate_position_limit_alarm_count == ((Alarm_Upload_Timer * 60) / (8 * (Scan_Alarm_Interval / A_Second)))  )
          {
            gate_position_limit_alarm_count = 0;
          }
        }
        gate_position_limit_alarm_count++;
      }

      else
      {
        if( rk.flag.upload_alarming_Gate_Positon_Overlimit )
        {
          rk.flag.upload         = true;
          rk.upload.alarm_status = Release_Alarm;
          rk.upload.alarm_type   = Gate_Positon_Overlimit;
          upload_package         = upload_alarm_package;
          upload_package_init();
          upload_package_crc_end( upload_package() );
          rk.flag.upload_alarming_Gate_Positon_Overlimit = false;
        }
      }
    }
  }
  rk.upload.scan_alarm_step++;
}
//上游水位计通讯故障
//下游水位计通讯故障
//流量计通讯故障
//流速计通讯故障
//渗压计通讯故障
//扭矩传感器通讯故障
//荷重传感器通讯故障
//太阳能板故障


void scan_malfunction_signal( void )
{

  static int water_level_upstream_malfunction_count     = 0;
  static int water_level_downstream_malfunction_count   = 0;
  static int flowmeter_malfunction_count                = 0;

  if( rk.upload.scan_malfunction_step == 8 )
  {
    rk.upload.scan_malfunction_step = 0;
  }

  // 上游水位计通讯故障
  if( rk.upload.scan_malfunction_step == 0 )
  {
    if( rk.CONFIG.FLOWMETER == okey )
    {
      if( (rk.timer.water_level_upstream_stop_work_timer >= Malfunction_Timer_Max) )
      {
        if( water_level_upstream_malfunction_count == 0 )
        {
          rk.flag.upload                  = true;
          rk.upload.malfunction_status    = Malfunctioning;
          rk.upload.malfunction_type      = Water_Level_Upstream_Link;
          upload_package                  = upload_malfunction_package;
          upload_package_init();
          upload_package_crc_end( upload_package() );
          rk.flag.upload_malfunction_water_level_upstream_link = true;
        }
        else
        {
          if( water_level_upstream_malfunction_count == ((Malfunction_Upload_Timer * 60) / (8 * (Scan_Malfunction_Interval / A_Second)))  )
          {
            water_level_upstream_malfunction_count = 0;
          }
        }
        water_level_upstream_malfunction_count++;
      }
      else
      {
        // 解除
        if( rk.flag.upload_malfunction_water_level_upstream_link )
        {
          rk.flag.upload                = true;
          rk.upload.malfunction_status  = Release_Malfunction;
          rk.upload.malfunction_type    = Water_Level_Upstream_Link;
          upload_package                = upload_malfunction_package;
          upload_package_init();
          upload_package_crc_end( upload_package() );
          rk.flag.upload_malfunction_water_level_upstream_link = false;
        }
      }
    }
  }

  // 下游水位计通讯故障
  else if( rk.upload.scan_malfunction_step == 1 )
  {
    if( rk.CONFIG.FLOWMETER == okey )
    {
      if( (rk.timer.water_level_downstream_stop_work_timer >= Malfunction_Timer_Max)  )
      {
        if( water_level_downstream_malfunction_count == 0 )
        {
          rk.flag.upload                  = true;
          rk.upload.malfunction_status    = Malfunctioning;
          rk.upload.malfunction_type      = Water_Level_Downstream_Link;
          upload_package                  = upload_malfunction_package;
          upload_package_init();
          upload_package_crc_end( upload_package() );
          rk.flag.upload_malfunction_water_level_downstream_link = true;
        }
        else
        {

          if( water_level_downstream_malfunction_count == ((Malfunction_Upload_Timer * 60) / (8 * (Scan_Malfunction_Interval / A_Second))) )
          {
            water_level_downstream_malfunction_count = 0;
          }
        }
        water_level_downstream_malfunction_count++;
      }
      else
      {
        // 解除
        if( rk.flag.upload_malfunction_water_level_downstream_link )
        {
          rk.flag.upload                = true;
          rk.upload.malfunction_status  = Release_Malfunction;
          rk.upload.malfunction_type    = Water_Level_Downstream_Link;
          upload_package                = upload_malfunction_package;
          upload_package_init();
          upload_package_crc_end( upload_package() );
          rk.flag.upload_malfunction_water_level_downstream_link = false;
        }
      }
    }
  }
  // 流量计通讯故障
  else if( rk.upload.scan_malfunction_step == 2 )
  {
    if( rk.CONFIG.FLOWMETER == okey )
    {
      if( (rk.timer.flowmeter_stop_work_timer >= Malfunction_Timer_Max) )
      {
        if( flowmeter_malfunction_count == 0 )
        {
          rk.flag.upload                  = true;
          rk.upload.malfunction_status    = Malfunctioning;
          rk.upload.malfunction_type      = Flowmeter_Link;
          upload_package                  = upload_malfunction_package;
          upload_package_init();
          upload_package_crc_end( upload_package() );
          rk.flag.upload_malfunction_flowmeter_link = true;
        }
        else
        {

          if( flowmeter_malfunction_count == ((Malfunction_Upload_Timer * 60) / (8 * (Scan_Malfunction_Interval / A_Second))) )
          {
            flowmeter_malfunction_count = 0;
          }
        }
        flowmeter_malfunction_count++;
      }
      else
      {
        // 解除
        if( rk.flag.upload_malfunction_flowmeter_link )
        {
          rk.flag.upload                = true;
          rk.upload.malfunction_status  = Release_Malfunction;
          rk.upload.malfunction_type    = Flowmeter_Link;
          upload_package                = upload_malfunction_package;
          upload_package_init();
          upload_package_crc_end( upload_package() );
          rk.flag.upload_malfunction_flowmeter_link = false;
        }
      }
    }
  }


  // 流速计通讯故障
  else if( rk.upload.scan_malfunction_step == 3 )
  {

  }

  // 渗压计通讯故障
  else if( rk.upload.scan_malfunction_step == 4 )
  {

  }

  // 编码器传感器通讯故障
  else if( rk.upload.scan_malfunction_step == 5 )
  {

  }

  // 荷重传感器通讯故障
  else if( rk.upload.scan_malfunction_step == 6 )
  {

  }

  // 太阳能板故障
  else if( rk.upload.scan_malfunction_step == 7 )
  {

  }
  rk.upload.scan_malfunction_step++;
}

void scan_whether_to_upload( void )
{
  char str[56];

  if( BOOTLOADER )
  {
    return;
  }
  if( rk.timer.scan_alarm_timer >= Scan_Alarm_Interval )
  {
    /* 扫描报警信号 */
    scan_alarm_signal();
    rk.timer.scan_alarm_timer = 0;
  }
  if( rk.timer.scan_malfunction_timer >= Scan_Malfunction_Interval )
  {
    /* 扫描故障信号 */
    scan_malfunction_signal();
    rk.timer.scan_malfunction_timer = 0;
  }

  if( rk.timer.upload_to_server_heart_timer >= Heart_Data_Upload_Cycle )   // 心跳  每隔60s 主动上报
  {
    upload_package = upload_heartbeat_package;
    upload_package_init();
    upload_package_crc_end( upload_package() );
    rk.timer.upload_to_server_heart_timer = 0;

    uart_log("device send heart package!\r\n");

    return ;
  }

  if( rk.flag.control_mode_change == true )  // 切换模式后主动上报
  {
     upload_package = upload_switch_mode_package;
     upload_package_init();
     upload_package_crc_end( upload_package() );
     rk.flag.control_mode_change = false;
     sprintf(str, "device send switch mode package, mode : %d\r\n",rk.parameter.control_object );
     uart_log( str );

     uart_log("device send switch mode package!\r\n");
     return ;
  }

  if( rk.timer.function_data_upload_timer >= rk.parameter.func_data_cycle )   // 业务数据  每隔5分钟  主动上报
  {
    rk.flag.func_data_initiative_update = true;

    upload_package = upload_function_data_package;
    upload_package_init();
    upload_package_crc_end( upload_package() );
    rk.timer.function_data_upload_timer = 0;

    uart_log("device send function data package!\r\n");

    return ;
  }

  if( rk.timer.THA_data_upload_timer >= rk.parameter.THA_data_cycle ) // 工况数据  每隔30s 主动上报
  {
    rk.flag.THA_data_initiative_update = true;

    upload_package = upload_THA_data_package;
    upload_package_init();
    upload_package_crc_end( upload_package() );
    rk.timer.THA_data_upload_timer = 0;

    uart_log("device send THA data package!\r\n");

    return ;
  }
}

void hex_to_str(const uint8_t *data, int len, char *output) {
    const char hex_chars[] = "0123456789ABCDEF";
    for (int i = 0; i < len; i++) {
        output[2*i]   = hex_chars[(data[i] >> 4) & 0x0F]; // 处理高四位
        output[2*i+1] = hex_chars[data[i] & 0x0F];       // 处理低四位
    }
    output[2*len] = '\0'; // 添加字符串结束符
}

void upload_data_to_server( void )
{
  if( rk.timer.upload_to_server_timer >= Upload_To_Server_Timer_Max )
  {
    rk.timer.upload_to_server_timer = 0;

    // 扫描是否要主动上传
    scan_whether_to_upload();

    if( rk.flag.device_login_success == false )
    {
      return ;
    }

    if( (rk.flag.upload_data_is_fanction_THA_heart_data == true) && (rk.flag.recv_fanction_THA_heart_data_confirm == false) )
    {
      // 如果此包数据为工况数据或业务数据，且未收到确认回复，则返回
      // 等待服务器端的确认回复超时则再次进行发送该包数据
      if( rk.timer.wait_confirm_timeout_timer >= 5 * A_Second )
      {
        rk.timer.wait_confirm_timeout_timer = 0;
        rk.flag.upload_data_is_fanction_THA_heart_data = false;
      }
      return ;
    }
    else if( (rk.flag.upload_data_is_fanction_THA_heart_data == true) && (rk.flag.recv_fanction_THA_heart_data_confirm == true) )
    {
      // 如果此包数据为工况数据或业务数据，且收到确认回复，则进行将数据出队，进行下一包的传输
      rk.flash_cycle_queue.head += rk.flash_cycle_queue.read_len;
      rk.flash_cycle_queue.head %= Cycle_Queue_Len_Max;
      HAL_RTCEx_BKUPWrite( &hrtc, RTC_BKP_DR3, rk.flash_cycle_queue.head );
      HAL_Delay(10);
      rk.flag.upload_data_is_fanction_THA_heart_data = false;
      rk.flag.recv_fanction_THA_heart_data_confirm = false;
    }

    if( rk.flash_cycle_queue.head < rk.flash_cycle_queue.tail )
    {
      from_exflash_read_package( &rk.flash_cycle_queue );
      // 如果此包数据为工况数据或业务数据，发送该包数据，等待确认回复
      if( (rk.flash_cycle_queue.read_data[Package_User_Data_Region_Size] == AFN_Fanction_Data) || (rk.flash_cycle_queue.read_data[Package_User_Data_Region_Size] == AFN_THA_Data) )
      {
        rk.timer.wait_confirm_timeout_timer = 0;
        EC20_send_data( rk.flash_cycle_queue.read_data, rk.flash_cycle_queue.read_len );
        rk.flag.upload_data_is_fanction_THA_heart_data = true;
      }
      else
      {
        // 如果此包数据不是工况数据或业务数据，则发送数据并将数据出队。
        EC20_send_data( rk.flash_cycle_queue.read_data, rk.flash_cycle_queue.read_len );
        sync_buf_read_dequeue( &rk.flash_cycle_queue );
        HAL_Delay(10);
      }

//      hex_to_str( rk.upload.txbuf, rk.upload.txbuf[Package_Len_Pos]+Package_Aside_From_User_Data, str );
//      HAL_Delay(30);
      uart_log("EC20 send data!\r\n");

//      uart_log( str );
//      uart_log( "\r\n" );

    }
//    else if( rk.flash_cycle_queue.head > rk.flash_cycle_queue.tail )
//    {
//      rk.flash_cycle_queue.tail = 0;
//      rk.flash_cycle_queue.head = 0;
//      uart_log("exflash data abnormal!\r\n");
//    }

  }
}